#!/usr/bin/python3
# -*- coding: utf-8 -*-

from collections import Iterable

from ._commons import db
from ..core.entities import PRJ_UNDEPLOYED


class ProjectPO(db.Model):
    """项目。"""
    __tablename__ = 'PROJECT'

    name = db.Column('PRJ_NAME', db.String(100), primary_key=True, nullable=False)
    description = db.Column('DESCRIPTION', db.String(500))
    version_number = db.Column('VERSION_NUMBER', db.String(40))
    status = db.Column('STATUS', db.Integer, default=PRJ_UNDEPLOYED, nullable=False)
    last_timestamp = db.Column('LAST_TIMESTAMP', db.DateTime)
    last_duration = db.Column('LAST_DURATION', db.Interval)
    locked = db.Column('LOCKED', db.Boolean, default=False, nullable=False)
    enabled = db.Column('ENABLED', db.Boolean, default=True, nullable=False)
    jobs = db.relationship('ProjectJobPO', lazy='select', cascade='all,delete-orphan')
    nodes = db.relationship('ProjectNodePO', lazy='select', cascade='all,delete-orphan')

    def set_jobs(
            self,
            value: Iterable = None,
            *jobs
    ):
        """设置关联的任务名称。

        :param value: 关联的任务名称。
        :param jobs: 所有关联的任务名称。
        """
        self.jobs.clear()
        if value:
            for name in value:
                self._add_job(name)
        if jobs:
            for name in jobs:
                self._add_job(name)

        return self

    def set_nodes(
            self,
            value: Iterable = None,
            *nodes
    ):
        """设置关联的目标节点。

        :param value: 关联的目标节点。
        :param nodes: 所有关联的目标节点。
        """
        self.nodes.clear()
        if value:
            for node in value:
                self._add_node(node)
        if nodes:
            for node in nodes:
                self._add_node(node)

        return self

    def _add_job(
            self,
            name: str
    ):
        if name is None or name.isspace():
            return

        self.jobs.append(ProjectJobPO(name=name))

    def _add_node(
            self,
            name: str
    ):
        if name is None or name.isspace():
            return

        self.nodes.append(ProjectNodePO(name=name))

    @property
    def jobs_names(self) -> tuple:
        """获取任务名称列表。"""
        return tuple(job.name for job in self.jobs)

    @property
    def node_names(self) -> tuple:
        """获取目标节点名称列表。"""
        return tuple(node.name for node in self.nodes)


class ProjectJobPO(db.Model):
    """项目关联的任务。"""
    __tablename__ = 'PROJECT_JOB'

    project_name = db.Column('PRJ_NAME', db.ForeignKey('PROJECT.PRJ_NAME'), primary_key=True, nullable=False)
    name = db.Column('JOB_NAME', db.String(100), primary_key=True, nullable=False)


class ProjectNodePO(db.Model):
    """项目关联的目标节点。"""
    __tablename__ = 'PROJECT_NODE'

    project_name = db.Column('PRJ_NAME', db.ForeignKey('PROJECT.PRJ_NAME'), primary_key=True, nullable=False)
    name = db.Column('NODE_NAME', db.ForeignKey('NODE.NODE_NAME'), primary_key=True, nullable=False)


class PkgPO(db.Model):
    """软件包。"""
    __tablename__ = 'PRJ_PKG'

    prj_name = db.Column('PRJ_NAME', db.ForeignKey('PROJECT.PRJ_NAME'), primary_key=True, nullable=False)
    version_number = db.Column('VERSION_NUMBER', db.String(40), primary_key=True, nullable=False)
    commit = db.Column('COMMIT', db.String(500), nullable=False)
    timestamp = db.Column('TIMESTAMP', db.DateTime, index=True, nullable=False)
    file_path = db.Column('FILE_PATH', db.String(500), nullable=False)
